package biz

import (
	"context"
	"github.com/go-kratos/kratos/v2/log"
	adminRoleApi "go-skeleton/api/admin/service/admin_role"
	"go-skeleton/app/admin/service/internal/data/ent"
	"go-skeleton/pkg/util/tool"
	"google.golang.org/protobuf/types/known/emptypb"
)

type AdminRoleRepo interface {
	Save(context.Context, *ent.AdminRole) (*ent.AdminRole, error)
	Update(context.Context, *ent.AdminRole) (*ent.AdminRole, error)
	FindByID(context.Context, int64) (*ent.AdminRole, error)
	FindByKeys(context.Context, []string) ([]*ent.AdminRole, error)
	List(context.Context, string, int, int) ([]*ent.AdminRole, int, error)
	ListAll(context.Context) ([]*ent.AdminRole, error)
	Del(context.Context, int64) error
}

type AdminRoleBiz struct {
	repo AdminRoleRepo
	log  *log.Helper
}

func NewAdminRoleBiz(repo AdminRoleRepo, logger log.Logger) *AdminRoleBiz {
	return &AdminRoleBiz{repo: repo, log: log.NewHelper(log.With(logger, "module", "biz/admin/role"))}
}

func (b *AdminRoleBiz) entToProto(role *ent.AdminRole) (dbData *adminRoleApi.RoleInfo) {
	return &adminRoleApi.RoleInfo{
		Id:        role.ID,
		RoleName:  role.RoleName,
		RoleKey:   role.RoleKey,
		Status:    role.Status,
		Describe:  role.Describe,
		MenuAuth:  role.MenuAuth,
		BtnAuth:   role.BtnAuth,
		CreatedAt: role.CreatedAt.Format(tool.DefaultTimeFormat),
	}
}

func (b *AdminRoleBiz) protoToEnt(role *adminRoleApi.RoleInfo) *ent.AdminRole {
	return &ent.AdminRole{
		ID:       role.Id,
		RoleName: role.RoleName,
		RoleKey:  role.RoleKey,
		Status:   role.Status,
		Describe: role.Describe,
		MenuAuth: role.MenuAuth,
		BtnAuth:  role.BtnAuth,
	}
}

func (b *AdminRoleBiz) Save(ctx context.Context, req *adminRoleApi.RoleInfo) (resp *adminRoleApi.RoleInfo, err error) {
	saveMenu, err := b.repo.Save(ctx, b.protoToEnt(req))
	if err != nil {
		return
	}
	resp = b.entToProto(saveMenu)

	return
}

func (b *AdminRoleBiz) Update(ctx context.Context, req *adminRoleApi.RoleInfo) (resp *adminRoleApi.RoleInfo, err error) {
	updateMenu, err := b.repo.Update(ctx, b.protoToEnt(req))
	if err != nil {
		return
	}
	resp = b.entToProto(updateMenu)

	return
}

func (b *AdminRoleBiz) FindByID(ctx context.Context, id int64) (*ent.AdminRole, error) {
	return b.repo.FindByID(ctx, id)
}

func (b *AdminRoleBiz) FindByRoleKeys(ctx context.Context, keys []string) ([]*ent.AdminRole, error) {
	return b.repo.FindByKeys(ctx, keys)
}

func (b *AdminRoleBiz) GetRole(ctx context.Context, req *adminRoleApi.GetRoleRequest) (resp *adminRoleApi.GetRoleReply, err error) {
	resp = &adminRoleApi.GetRoleReply{
		Data:  make([]*adminRoleApi.RoleInfo, 0),
		Total: 0,
	}

	list, total, err := b.repo.List(ctx, req.RoleName, int(req.PageNum), int(req.PageSize))
	if err != nil {
		return
	}

	for _, v := range list {
		resp.Data = append(resp.Data, b.entToProto(v))
		resp.Total = int32(total)
	}
	return
}

func (b *AdminRoleBiz) GetAllRole(ctx context.Context) (resp *adminRoleApi.GetAllRoleReply, err error) {
	resp = &adminRoleApi.GetAllRoleReply{
		Data: make([]*adminRoleApi.RoleInfo, 0),
	}

	list, err := b.repo.ListAll(ctx)
	if err != nil {
		return
	}

	for _, v := range list {
		resp.Data = append(resp.Data, b.entToProto(v))
	}
	return
}

func (b *AdminRoleBiz) DelRole(ctx context.Context, id int64) (resp *emptypb.Empty, err error) {
	err = b.repo.Del(ctx, id)

	return
}
